// -----------------------------------------------------------------------------
// This source file is part of Matrix Platform
// 	(Universal .NET Software Development Platform)
// For the latest info, see http://www.matrixplatform.com
// 
// Copyright (c) 2009-2010, Ingenious Ltd
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// -----------------------------------------------------------------------------
using System;
using System.IO;
using System.Windows.Forms;
using Matrix.Common.Diagnostics.TracerCore;
using Matrix.Common.Diagnostics.TracerCore.Items;
using Matrix.Common.Diagnostics.TracerCore.Sinks;
using Matrix.Common.Extended;
using Matrix.Common.FrontEnd;
using Matrix.Common.Sockets.NetworkTracer;

namespace Matrix.Common.Diagnostics.Application
{
    /// <summary>
    /// Main tracer application form.
    /// </summary>
    public partial class FormDiagnostics : Form
    {
        string _filePath = null;

        FileSystemWatcher _watcher = new FileSystemWatcher();

        long _lastFilePos = 0;

        FileStream _fs = null;

        NetworkTracer _tracer = new NetworkTracer();

        StreamReader _reader = null;

        string _defaultTitle = string.Empty;

        /// <summary>
        /// Constructor.
        /// </summary>
        public FormDiagnostics()
        {
            InitializeComponent();

            _defaultTitle = this.Text;

            TracerItemKeeperSink sink = new TracerItemKeeperSink(_tracer);
            sink.MaxItems = 1000000;
            _tracer.Add(sink);

            _watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size;
            _watcher.Changed += new FileSystemEventHandler(_watcher_Changed);

            //_tracer.StartTraceServer(TracerNet.DefaultPort);
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            tracerControlSource.Tracer = _tracer;

            Tracer systemTracer = new Tracer();
            TracerItemKeeperSink sink = new TracerItemKeeperSink(systemTracer);
            sink.MaxItems = 100000;
            SystemMonitor.AssignTracer(systemTracer);
            tracerControlLocal.Tracer = SystemMonitor.Tracer;
        }


        /// <summary>
        /// 
        /// </summary>
        private void toolStripButtonLoad_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Assemblies (*.log; *.txt)|*.log;*.txt";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                _tracer.Clear(false);

                _filePath = ofd.FileName;
                _watcher.Path = Path.GetDirectoryName(_filePath);
                _watcher.Filter = Path.GetFileName(_filePath);

                _watcher.EnableRaisingEvents = true;


                if (_fs != null)
                {
                    _fs.Dispose();
                }

                _lastFilePos = 0;

                this.Text = _defaultTitle + " - " + _filePath;

                toolStripButtonUpdate_Click(this, EventArgs.Empty);
            }
        }

        void _watcher_Changed(object sender, FileSystemEventArgs e)
        {
            if (_fs == null
                || e.ChangeType == WatcherChangeTypes.Deleted
                || e.ChangeType == WatcherChangeTypes.Created)
            {
                if (_reader != null)
                {
                    _reader.Dispose();
                    _reader = null;
                }

                if (_fs != null)
                {
                    _fs.Dispose();
                    _fs = null;
                }

                if (e.ChangeType == WatcherChangeTypes.Deleted)
                {
                    return;
                }
                
                try
                {
                    _fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    _reader = new StreamReader(_fs);
                }
                catch (Exception ex)
                {
                    SystemMonitor.Error(ex.Message);
                    _reader = null;
                    _fs.Dispose();
                    _fs = null;
                    return;
                }
            }

            if (_fs == null || _fs.CanRead == false)
            {
                return;
            }

            if (_fs.Length < _lastFilePos - 10)
            {// File was rewritten start from beggining.
                _lastFilePos = 0;
            }

            _fs.Seek(_lastFilePos, SeekOrigin.Begin);

            string line = _reader.ReadLine();
            while (line != null)
            {
                TracerItem item = TracerItem.ParseFileItem(line);
                if (item != null)
                {
                    _tracer.Add(item);
                }
                //ParseLine(line);
                line = _reader.ReadLine();
            }

            _lastFilePos = _fs.Position;
        }


        //void ParseLine(string line)
        //{
        //if (string.IsNullOrEmpty(line))
        //{
        //    return;
        //}

        //try
        //{
        //    string[] substrings = line.Split('|');

        //    if (substrings.Length < 4)
        //    {
        //        SystemMonitor.OperationError("Failed to parse tracer item line [" + line + ", Not enough substrings generated].");
        //        return;
        //    }

        //    TracerItem.TypeEnum type = (TracerItem.TypeEnum)Enum.Parse(typeof(TracerItem.TypeEnum), substrings[0]);

        //    long index = 0;
        //    long.TryParse(substrings[1], out index);

        //    DateTime time;
        //    try
        //    {
        //        string dateTime = substrings[2];
        //        string[] dateTimeParts = dateTime.Split('/');
        //        string[] subParts = dateTimeParts[2].Split(' ');
        //        TimeSpan timeSpan = TimeSpan.Parse(subParts[1]);

        //        time = new DateTime(int.Parse(subParts[0]), int.Parse(dateTimeParts[0]),
        //            int.Parse(dateTimeParts[1]), timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds);
        //    }
        //    catch(Exception ex2)
        //    {
        //        SystemMonitor.OperationError("Failed to parse tracer item line [" + line + ", " + ex2.Message + "].");
        //        time = DateTime.MinValue;
        //    }

        //    //if (DateTime.TryParse(substrings[2], out time) == false)
        //    //{
        //    //    time = DateTime.MinValue;
        //    //}

        //    TracerItem item = new TracerItem(type, time, index.ToString() + "  " + substrings[substrings.Length - 1]);
        //    _tracer.Add(item);

        //}
        //catch(Exception ex)
        //{
        //    SystemMonitor.OperationError("Failed to parse tracer item line [" + line + ", " + ex.Message + "].");
        //}
        //}

        private void toolStripButtonUpdate_Click(object sender, EventArgs e)
        {
            GeneralHelper.FireAndForget(delegate()
                                            {
                                                _watcher_Changed(null, new FileSystemEventArgs(WatcherChangeTypes.Created, _watcher.Path, _watcher.Filter));
                                                WinFormsHelper.BeginFilteredManagedInvoke(tracerControlSource, tracerControlSource.UpdateUI);
                                            });
        }


    }
}
